<template>
	<div class="p30 angbg">
		<div>音频可视化</div>
		<div class="width-full lookbrod mb30">
			<canvas id="myCanvas" style="border:1px solid #000;width:100%;height:100%"></canvas>
		</div>
		 <!-- // 时间与进度条 -->
		<div class="flex">
			<div>{{timefitter(begintime)}}</div>
			<el-progress class="flex-1 pl20 pr20 progress"  :show-text='false' :percentage="percentage" color="#67c23a" />
			<div>{{timefitter(endtime)}}</div>
		</div>
		<!-- // 左右开始暂停 -->
		<div class="flex flex-around p20">
			<div class="text-center">
				<div class="iconfont icon-skip-back-fill btnbg " :class="isclick? 'actbtn' : ''" @click="clickit"></div>
			</div>
			<div class="text-center" v-if="isplay">
				<div class="iconfont icon-zanting1 btnbg " :class="isclick? 'actbtn' : ''" @click="pause"></div>
			</div>
			<div class="text-center" v-else>
				<div class="iconfont icon-icon_play btnbg " :class="isclick? 'actbtn' : ''" @click="play"></div>
			</div>
			<div class="text-center">
				<div class="iconfont icon-skip-forward-fill btnbg " :class="isclick? 'actbtn' : ''" @click="clickit"></div>
			</div>
		</div>
		<!-- // 隐藏的音频原生 -->
		<div class="audiof">
			<audio id='myaudio'  @canplay="canplay" @play='onplay' controls :src="videosrc"></audio>
		</div>
	</div>
</template>

<script setup>
	import { ref,nextTick,computed ,onMounted} from 'vue';
	import videosrc from '@/assets/img/test.mp3'
	let myaudio = null
	nextTick(()=>{
		myaudio = document.getElementById('myaudio')
		// 监听播放 中
		myaudio.addEventListener('timeupdate', (event) => {
			// 当前播放时间赋值
			begintime.value = event.target.currentTime
		});
	})
	

	onMounted(() => {
		initcanvas()
		draw()
	})
	let initcanvas = function(){
		let canvas = document.getElementById("myCanvas");
		
		let ctx = canvas.getContext("2d"); 
		
		ctx.fillRect(0, 0, 300, 150);
		ctx.fillStyle = '#000'
	}
	
	// 准备好播放了！
	let canplay = ()=>{
		 endtime.value =  myaudio.duration.toFixed()
	}

	// 是否正在播放
	let isplay = ref(false)
	// 开始时间
	let begintime = ref(0)
	// 总时间
	let endtime = ref(0)
	// 计算当前进度
	let percentage = computed(() => {
		return begintime.value * 100 / endtime.value 
	}) 
	// 格化显示的时间
	let timefitter = (time)=>{
		let values,left ,right;
		left = parseInt(time/60)
		right =  Math.ceil(time % 60)
		function addzro(num){
			if(num < 10) {
				num = '0' + num
			}
			return num
		}
		left = addzro(left)
		right = addzro(right)
		values = left + ':' + right
		return values
	}
	
	// 封装一个按钮的点击效果，通过调用 Promise 来实现延时后执行的动画
	let isclick = ref(false)
	let clickprmisese = ()=>{
		isclick.value = true
		return new Promise((res,rej)=>{
			setTimeout(function(){
				isclick.value = false
				res('完成了')
			}, 300);
		})
	}
	
	let clickit = ()=>{
		clickprmisese().then(res=>{
			console.log(res,'---')
		})
	}
	
	// 点击播放
	let play = ()=>{
		clickprmisese().then(res=>{
			isplay.value = true
			myaudio.play()
		})
	}
	// 开始播放后调用的函数
	let isInit = false
	let dataArry ,analyser ,source ,audCtx
	let onplay = ()=> {
		if(isInit){
			return
		}
		audCtx = new AudioContext() // 创建音频上下文
		analyser = audCtx.createAnalyser();
		source = audCtx.createMediaElementSource(myaudio)   //创建音频源节点
		analyser.fftSize = 512;
		dataArry =  new Uint8Array(analyser.frequencyBinCount)
		source.connect(analyser);
		analyser.connect(audCtx.destination)
		
		isInit = true
	}
	let draw = () => {
	      let cvs = document.getElementById("myCanvas");
	      let ctx = cvs.getContext("2d");
	      requestAnimationFrame(draw);
	      //清空画布
	      const { width, height } = cvs;
	      ctx.clearRect(0, 0, width, height);
		   // ctx.fillRect(0, 0, width, width);
		  
		  ctx.fillStyle = '#000'
	      //判断分析器是否初始化
	      if (!isInit) {
	        return;
	      }
	      //分析器节点分析出数据到数组中
	      analyser.getByteFrequencyData(dataArry); //让分析器节点分析当前音频源数据，把分析结果添加到数组
		  
		  console.log(dataArry)
		  
	      const len = dataArry.length / 2.5;
	      const barWidth = width / len /2 ;
		  // function color16(){//十六进制颜色随机
		  //   const r = Math.floor(Math.random()*256);
		  //   const g = Math.floor(Math.random()*256);
		  //   const b = Math.floor(Math.random()*256);
		  //   const color = `#${r.toString(16)}${g.toString(16)}${b.toString(16)}`;
		  //   return color;
		  // }
	      ctx.fillStyle =  "#78c5f7";
	      for (let i = 0; i < len; i++) {
	        const data = dataArry[i]; //<256
	        const barHeight = (data / 255) * height;
	        const x1 = i * barWidth + width / 2;
	        const x2 = width / 2 - (i + 1) * barWidth;
	        const y = height - barHeight;
	        ctx.fillRect(x1, y, barWidth, barHeight);
	        ctx.fillRect(x2, y, barWidth, barHeight);
	      }
	    }

	// 点击暂停
	let pause = ()=>{
		clickprmisese().then(res=>{
			isplay.value = false
			myaudio.pause()
		})
	}
	
</script>



<style lang="scss" scoped>
	.btnbg{
		-webkit-appearance: none;
		box-shadow: -10px -10px 15px rgba(255,255, 255, .5),10px 10px 15px rgba(70,70, 70, .12);
		width:50px;
		line-height: 50px;
		border-radius: 50%;
	}
	
	.actbtn:hover{
		box-shadow: -10px -10px 15px rgba(255,255, 255, .5),
		10px 10px 15px rgba(70,70, 70, .12),
		inset -15px -15px 15px rgba(255,255, 255, .5),
		inset 15px 15px 15px rgba(70,70, 70, .12);
		color: rgba(85, 170, 0, 0.5);
	}
	.audiof{
		display: none;
		
	}
	.lookbrod{
		height: 50%;
		background-color: #000;
	}
	.angbg{
		background-color: #ececec;
		height: 100%;
	}

</style>

<style lang="scss">
	.progress{
		.el-progress-bar{
			.el-progress-bar__outer{
				background-color: #e5e5e5;
			}
		}
	}
</style>